import { Component } from '@angular/core';
import { NavController, ToastController, NavParams, Nav } from 'ionic-angular';
import { BarcodeScanner } from '@ionic-native/barcode-scanner';
import { PreConfigPage } from '../../pages/preconfig/preconfig';
import { RestService } from '../../app/services/rest.service';
import { Observable } from 'rxjs/Observable';
import { TabsPage } from '../tabs/tabs';
import { LoginPage } from '../login/login';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'page-scan',
  templateUrl: 'scan.html',
})
export class ScanPage {
  institution = {
    id: this.rest.institutionId,
    instName: "护适通"
  }
  showButton = false;
  devices = [];
  url = 'data/person';
  person = {
    id: null,
    address: "",
    awayAlarm: true,
    birth: null,
    breatheLow: 10,
    breatheUp: 25,
    checkinRecord: "",
    checkinTime: 1542561221760,
    checkoutTime: 0,
    contact1Address: "",
    contact1Name: "",
    contact1Phone: "",
    contact1Sex: 0,
    contact2Address: "",
    contact2Name: "",
    contact2Phone: "",
    contact2Sex: 0,
    device1Id: "",
    device1: 0,
    deviceAlarm: false,
    deviceAlarmFlag: true,
    education: 0,
    heartLow: 40,
    heartUp: 90,
    move: 10,
    nation: "",
    nurseId: "",
    personName: "13000000001",
    phone: "",
    rid: "",
    sex: 0,
    kilo: 0,
    longitude:0,
    latitude:0,
    sideAlarm: true,
    silent: false,
    turnOverReminder: 0,
    turnOverReminderAlarmFlag: false,
    upAlarm: true
  };
  deviceName = "";
  scannedCode = null;
  constructor(public navCtrl: NavController,
    public navParams: NavParams,
    private nav: Nav,
    private toastCtrl: ToastController,
    private translate: TranslateService,
    private rest: RestService,
    private barcodeScanner: BarcodeScanner) {
    if (navParams.data.personName) {
      // Navigate from loginPage
      this.person.personName = navParams.data.personName;
      this.showButton = true;
    } else if (navParams.data.personNamefromDvs) {
      // Navigate from DevicePage
      this.person.personName = navParams.data.personNamefromDvs;
      this.showButton = false;
    }
  }

  navBack() {
    this.navCtrl.pop();
  }
  scanCode() {
    this.barcodeScanner.scan().then(barcodeData => {
      this.scannedCode = barcodeData.text;
    },
      (err) => {
        console.log('Error: ', err);
        if (this.scannedCode == null) {
          //this is just for developing as barcodeScan doesn't work on PC environment.
          if (this.rest.developing == true) {
            this.scannedCode = "01CH020018";
          } else {
            this.showToast(this.translate.get('pleaseInputDeviceId')['value']);
          }
        }
      });
  }

  nextStep() {
    if (this.scannedCode == null) {
      this.showToast(this.translate.get('pleaseInputDeviceId')['value']);
      return;
    }
    if (!localStorage.getItem('devices')) {
      this.addDeviceCheckin()
    } else {
      this.addDevice()
    }
  }

  popData() {
    let callback = this.navParams.get('callback');
    let data: Object = {
      deviceId: this.scannedCode,
      deviceName: this.deviceName
    };
    callback(data);
    this.navCtrl.pop();
  }

  addDevice() {
    if (localStorage.getItem('devices').search(this.scannedCode) > 0) {
      console.log('Device Id already in on moblie');
      this.showToast(this.translate.get('alreadyMonitorDevice')['value']);
      return;
    }
    this.rest.getWithParams('/data/device/search/deviceId', {
      deviceId: this.scannedCode
    }).subscribe(resp => {
      if (resp['_embedded']['devices'].length > 0) {
        console.log('Device Id already in HST institution');
        //get the person Id navigate to Tabs
        this.person.device1Id = this.scannedCode;
        if (resp['_embedded']['devices'][0]["personId"] != "") {
          this.showToast(this.translate.get('nonEmptyDeviceMessage')['value']);
          console.log('Device Id already bound to other person');
        } else {
          this.popData()
        }
        // this.nav2Tabs();
      } else {
        //add Device
        this.rest.post('/data/device', { deviceId: this.scannedCode }).subscribe((resp) => {
          // link it to institution
          this.rest.link('data/device' + '/' + resp['id'] + '/institution', 'data/institution/' + this.institution.id).subscribe((resp) => {
            this.rest.getWithParams('/data/device/search/deviceId', {
              deviceId: this.scannedCode
            }).subscribe(resp => {
              console.log('DeviceId: ' + this.scannedCode + ' is added into HST institution');
              this.person.device1 = resp['_embedded']['devices'][0].id;
              // this.person.personName = this.scannedCode;
              this.person.device1Id = this.scannedCode;
              this.popData()
            }, message => {
              console.error('Failed to get deviceId: ' + message);
            });
          }, () => {
            console.error('Failed to link device to institution');
          });
        }, message => {
          // this.rest.showHttpError('addInstError', message);
        });
      }

    }, message => {
      console.error('Failed to get deviceId: ' + message);
    });

  }

  public bindPersonDevice(personIdIn, observableBatch) {
    const personId = personIdIn;

    observableBatch.push(this.rest.patch('/data/person' + '/' + personId, this.person));
    if (this.person['device1Id']) {
      observableBatch.push(this.rest.patch('/data/device/' + this.person['device1'], { personId: personId, personName: this.person.personName }));
    }

    Observable.forkJoin(observableBatch).subscribe((resp) => {
      console.log('Add person ' + this.person.personName + ' successfully!');
      localStorage.setItem('personName', this.person['personName']);
      this.devices.push({ id: this.person['device1Id'], name: this.deviceName, netwk: false, disabled: false, bind: true })
      localStorage.setItem('devices', JSON.stringify(this.devices));
      this.informPersonChange(personId, this.person['device1Id'], 'checkin');
      this.nav2Tabs();
    }, message => {
    });
    console.log("Check in Successfully");
  }

  addDeviceCheckin() {

    const observableBatch = [];
    observableBatch.push(this.rest.getWithParams('/data/device/search/deviceId', {
      deviceId: this.scannedCode
    }));
    observableBatch.push(this.rest.getWithParams('/data/person/search/name', {
      name: this.person['personName'],
      institutionId: this.rest.institutionId
    }));
    Observable.forkJoin(observableBatch).subscribe((data) => {

      const deviceExist = data[0]['_embedded']['devices'].length > 0;
      const personExist = data[1]['_embedded']['persons'].length > 0;

      const observableBatch = [];
      if (!deviceExist) {
        observableBatch.push(this.rest.post('/data/device', { deviceId: this.scannedCode }));
      }
      if (!personExist) {
        observableBatch.push(this.rest.post('/data/person', this.person));
      }
      if (observableBatch.length > 0) {
        Observable.forkJoin(observableBatch).subscribe((data1) => {
          const observableBatch = [];

          // NNN (New user, new device)
          if (!personExist && !deviceExist) {
            this.person.id = data1[1]['id'];
            this.person.device1 = data1[0]['id'];
            this.person.device1Id = this.scannedCode;
            const personId = data1[1]['id'];
            const deviceId = data1[0]['id'];
            observableBatch.push(this.rest.link('data/person' + '/' + personId + '/institution', 'data/institution/' + this.institution.id));
            observableBatch.push(this.rest.link('data/device' + '/' + deviceId + '/institution', 'data/institution/' + this.institution.id));
            this.bindPersonDevice(personId, observableBatch)
          }
          // NYN (New user, existing device not bound)
          else if (!personExist && deviceExist && data[0]['_embedded']['devices'][0]['personId'] == 0) {
            this.person.id = data1[0]['id'];
            this.person.device1 = data[0]['_embedded']['devices'][0].id;
            this.person.device1Id = this.scannedCode;
            const personId = data1[0]['id'];
            observableBatch.push(this.rest.link('data/person' + '/' + personId + '/institution', 'data/institution/' + this.institution.id));
            this.bindPersonDevice(personId, observableBatch)
          }
          // NYY (New user, existing device bound to other user)
          else if (!personExist && deviceExist && data[0]['_embedded']['devices'][0]['personId'] != 0) {
            this.showToast(this.translate.get('nonEmptyDeviceMessage')['value']);
            console.log('device already bond to other person!!!')
          }
          // YNN (Existing user, new device, user not bound)
          else if (personExist && !deviceExist && data[1]['_embedded']['persons'][0]['device1'] == 0) {
            this.person = data[1]['_embedded']['persons'][0];
            this.person.device1 = data1[0]['id'];
            this.person.device1Id = this.scannedCode;
            const personId = this.person['id'];
            const deviceId = this.person.device1;
            observableBatch.push(this.rest.link('data/device' + '/' + deviceId + '/institution', 'data/institution/' + this.institution.id));
            this.bindPersonDevice(personId, observableBatch)
          }
          // YNY (Existing user, new device, user bound to other device)
          else if (personExist && !deviceExist && data[1]['_embedded']['persons'][0]['device1'] != 0) {
            this.showToast(this.translate.get('pleaseInputDeviceId')['value'] + "/" + this.translate.get('skip')['value']);
            //roll back to remove the device just entered
            this.rest.delete('/data/device/' + data1[0]['id']).subscribe(result => {
            }, message => {
            });
          }
        })
      }
      else {
        // YYN (Existing user, Existing device, user and device not bound)
        if (personExist && deviceExist && data[0]['_embedded']['devices'][0]['personId'] == 0 && data[1]['_embedded']['persons'][0]['device1'] == 0) {
          this.person = data[1]['_embedded']['persons'][0];
          this.person.device1 = data[0]['_embedded']['devices'][0].id;
          this.person.device1Id = this.scannedCode;
          const personId = this.person['id'];
          this.bindPersonDevice(personId, observableBatch)
        }
        // YYY (Existing user, Existing device, bound each other)
        else if (personExist && deviceExist && data[0]['_embedded']['devices'][0]['personId'] == data[1]['_embedded']['persons'][0]['id']) {
          this.person = data[1]['_embedded']['persons'][0];
          localStorage.setItem('personName', this.person['personName']);
          this.devices.push({ id: this.person['device1Id'], name: this.deviceName, netwk: false, disabled: false, bind: true })
          localStorage.setItem('devices', JSON.stringify(this.devices));
          this.nav2Tabs();
        }
        else if (personExist && deviceExist && data[0]['_embedded']['devices'][0]['personId'] != data[1]['_embedded']['persons'][0]['id']) {
          this.showToast(this.translate.get('personDeviceNotMatch')['value']);
          console.log('device already bond to other person!!!')
        }
      }
    });

  }

  nav2Tabs() {
    this.navCtrl.push(TabsPage, { personName: localStorage.getItem('personName'), deviceName: this.deviceName });
  }

  public checkin() {

    this.rest.post('/' + this.url, this.person).subscribe((resp) => {
      const personId = resp['id'];
      const observableBatch = [];

      observableBatch.push(this.rest.link(this.url + '/' + personId + '/institution', 'data/institution/' + this.institution.id));

      if (this.person['bedId'] > 0) {
        observableBatch.push(this.rest.patch('/data/bed/' + this.person['bedId'], { personId: personId, personName: this.person.personName }));
      }

      if (this.person['device1Id']) {
        observableBatch.push(this.rest.patch('/data/device/' + this.person['device1'], { personId: personId, personName: this.person.personName }));
      }

      Observable.forkJoin(observableBatch).subscribe((resp) => {
        console.log('Add person ' + this.person.personName + ' successfully!');
        localStorage.setItem('personName', this.person['personName']);
        this.informPersonChange(personId, this.person['device1Id'], 'checkin');
        this.nav2Tabs();
      }, message => {
         //this.rest.showHttpError('AddPersonError', message);
       // this.showToast('AddPersonError');
      });
    }, message => {
       //this.rest.showHttpError('addPersonError', message);
     // this.showToast('AddPersonError');
    });
    this.showToast('Check in Successfully');
    console.log("Check in Successfully");
  }

  validateCheckin() {
    this.rest.getWithParams('/data/person/search/name', {
      name: this.person.personName,
      institutionId: this.rest.institutionId
    }).subscribe(resp => {
      const personExist = resp['_embedded']['persons'].length > 0;
      if (personExist) {
        this.person = resp['_embedded']['persons'][0];
        localStorage.setItem('personName', this.person['personName']);

        const deviceId = this.person['device1Id'];
        if (deviceId) {
          // const bindStatus = this.person['bind1Time'] > 0 && this.person['unbind1Time'] === 0;
          this.devices.push({ id: deviceId, name: this.deviceName, netwk: false, disabled: false, bind: true });
          localStorage.setItem('devices', JSON.stringify(this.devices));
        }

        this.nav2Tabs();
      } else if(this.rest.institutionId == 1){
        this.checkin();
      } else {
        this.nav.setRoot(LoginPage);
        this.showToast(this.translate.get('pleaseInputInstituteId')['value']);
      }
    }, message => {
      console.error('Failed to get all persons in: ' + message);
    });
  }


  informPersonChange(personId: string, devId:string,type: string) {
    // type could be checkin, checkout, delete, updateDevice, updateThreshold, updateBasic, updateContact, updateHospital
    this.rest.post('/data/configData', {
      personId: personId,
      devId:devId,
      type: type
    }).subscribe(() => {
    });
  }

  nav2preconfig() {
    this.navCtrl.push(PreConfigPage, {});
  }

  showToast(message) {
    const toast = this.toastCtrl.create({
      message: message,
      duration: 3000,
      position: 'middle'
    });

    toast.present(toast);
  }

}
